package com.arm.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;

import com.audio.common.CmdInfo;
import com.medzone.mcloud.background.BluetoothMessage;
import com.medzone.mcloud.background.abHelper.BFactory;
import com.medzone.mcloud.background.ecg.EcgProtocal;
import com.medzone.mcloud.background.util.BluetoothUtils;
import com.medzone.mcloud.background.util.IOUtils;

public class MeasureHelper {
	public interface ICommandCallback {
		void handleMessage(Message msg);
	}
	
	public final static int					BLOOD_PRESSURE							= 1;
	public final static int					BLOOD_PRESSURE_ARM						= 12;
	public final static int					BLOOD_PRESSURE_All						= 13;
	public final static int					BLOOD_OXYGEN                            = 2;
	public final static int					BLOOD_OXYGEN_ALL                        = 22;
	public final static int					BLOOD_OXYGEN_TWO                        = 21;
	public final static int					OXYGEN_RING                             = 200;
	public final static int					EAR_TEMPERATURE							= 3;
	public final static int					BLOOD_SUGAR                             = 4;
	public final static int					FETAL_HEART							    = 5;
	public final static int					ECG                                     = 6;
	public final static int					ECG2							        = 206;
	public final static int					URINE_ANALYSIS                          = 7;
	public final static int					BASE_TEMPERATURE						= 8;
	public final static int					BODY_FAT                                = 9;
	public final static int					ID_CARD							        = 100;
	public final static int					WELFARE_CARD                            = 101;
	public final static int					WELFARE_CARD2							= 104;
	public final static int					SJM                                     = 201;
	
	public final static int					SHOW_DEVICE_LIST						= 0x100;
	public final static int					UPDATE_DEVICE_LIST						= 0x101;
	public final static int					HIDE_DEVICE_LIST						= 0x102;
	public final static int					UPDATE_STATUS							= 0x200;
	public final static int					DEVICE_DETECTED							= 0x201;
	public final static int					MEASURE_RESULT							= 0x202;

	protected static final String TAG = "MeausreHelper";
	private static Context 					mContext;
	private ArrayList<String>				mDeviceLists							= new ArrayList<String>();
	private String							mDevAddress;
	private ArrayList<Integer>				mRssiLists							= new ArrayList<Integer>();
	private Integer							mRssi;
	private int                             mType;
	private static String tag = MeasureHelper.class.getSimpleName();
	public static final Object lock = new Object();
	private static MeasureHelper instance;
	private Messenger mSeverMessenger;
	private Messenger mClientMessenger;
	private List<ICommandCallback> listeners = new ArrayList<ICommandCallback>();

	public static synchronized MeasureHelper getInstance() {
		if (instance == null) {
			instance = new MeasureHelper();
		}
		return instance;
	}
	
	private MeasureHelper() {
	}

	public static void init(Context context) {
		mContext = context.getApplicationContext();
		getInstance().bind();
	}

	public static void unInit() {
		getInstance().unbind();
	}

	private ServiceConnection conn = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder binder) {
			mSeverMessenger = new Messenger(binder);
			open(":");
			Log.i(tag, "+onServiceConnected()");
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.i(tag, "+onServiceDisconnected()");
		}
	};

	private void bind() {

		if (mSeverMessenger != null) {
			return;
		}
		Log.i(tag, "+bind()");
		{
			mClientMessenger = new Messenger(handler);
			Intent intent = new Intent(mContext,
					com.medzone.mcloud.background.MMeasureService.class);
			mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
		}
	}

	private void unbind() {
		if (conn != null) {
			Log.i(tag, "+unbind()");
			mContext.unbindService(conn);
			mSeverMessenger = null;
			conn = null;
		}
	}

	public void addListener(ICommandCallback listener) {
		synchronized (lock) {
			if (!listeners.contains(listener)) {
				Log.i(tag, "+addListener():" + listener.hashCode());
				listeners.add(listener);
			}
		}
	}

	public void removeListener(ICommandCallback listener) {
		synchronized (lock) {
			if (listeners.contains(listener)) {
				listeners.remove(listener);
				Log.i(tag, "+removeListener():" + listener.hashCode());
			}
		}
	}

	public void open(int type) {
		mType = type;
		mDeviceLists.clear();
		mRssiLists.clear();
		String devAddr  = ":";
		if(devAddr != "" && devAddr != null && devAddr!=":")
			mDeviceLists.add(devAddr);
		open(devAddr);
	}
	
	public String[] getDeviceList() {
		return (String[]) mDeviceLists.toArray(new String[mDeviceLists.size()]);
	}
	
	public Integer[] getRssiList() {
		return (Integer[]) mRssiLists.toArray(new Integer[mRssiLists.size()]);
	}

	public void open(String addr) {
		mDevAddress = addr;
		sendCommand(BluetoothMessage.msg_open, 0, mDevAddress);
	}
	
	public void query() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.QUERY_TERMAINAL);
	}

	public void measure() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.START_MEASURE);
	}
	
	public void record() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.RECORD);
	}
	
	public void progress(){
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.MEASURE_PROGRESS);
	}
	
	public void cancelMeasure() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.PAUSE_MEASURE);
	}

	public void calabrateTime() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.CALABRATE_TIME);
	}
	
	public void calabrate() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.CALABRATE);
	}
	
	public void queryLatest() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.RESEND_LAST_DATA);
	}
	
	public void testBT() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.TEST_BT);
	}
	
	public void clearData() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.CLEAR_DATA);
	}
	public void close() {
		sendCommand(BluetoothMessage.msg_close, 0);
	}

	public void getStatus() {
		sendCommand(BluetoothMessage.msg_get_status, 0);
	}
	
	public void queryData() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.QUERY_DATA);
	}
	
	public void maternalAndChild() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.MATERNAL_AND_CHILD);
	}
	
	public void closeBT() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.CLOSE_BT);
	}
	
	public void closeDevice() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.CLOSE_DEVICE);
	}
	
	public void setTermainalTime() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.SET_TERMAINAL_TIME);
	}
	
	public void cache() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.CACHE);
	}
	
	public void setBlackTime() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.SET_BLACK_TIME);
	}
	
	public void setUserInfo() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.SET_USER_INFO);
	}
	
	public void getInstanceData() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.INSTANT_DATA);
	}
	
	public void getHistoryData() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.HISTORY_DATA);
	}
	
	public void detectStaticPressure() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.STATIC_PRESSURE);
	}
	
	public void setting() {
		sendCommand(BluetoothMessage.msg_send, BluetoothUtils.SETTING);
	}
	public void send(int cmd){
		sendCommand(BluetoothMessage.msg_send, cmd);
	}
	
	public void send(int cmd,byte[] params){
		sendCommand(BluetoothMessage.msg_send, cmd,params);
	}
	
	private void sendCommand(int what, int cmd, String param) {
		if (mSeverMessenger == null) return;

		Message msg = Message.obtain(null, 0);
		msg.what = what;
		msg.arg1 = mType|(cmd<<16);
		msg.arg2 = cmd;
		msg.obj = param;
		msg.replyTo = mClientMessenger;
		try {
			mSeverMessenger.send(msg);
		}
		catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	public void sendCommand(int what, int cmd, byte[] param) {
		if (mSeverMessenger == null) return;

		HashMap<String, byte[]> result = new HashMap<String, byte[]>();
		result.put("data", param);
		Message msg = Message.obtain(null, 0);
		msg.what = what;
		msg.arg1 = mType;
		msg.arg2 = cmd;
		msg.obj = result;
		msg.replyTo = mClientMessenger;
		try {
			mSeverMessenger.send(msg);
		}
		catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	public void sendCommand(int what, int cmd) {
		if (mSeverMessenger == null) return;

		Message msg = Message.obtain(null, 0);
		msg.what = what;
		msg.arg1 = mType;
		msg.arg2 = cmd;
		msg.obj = null;
		msg.replyTo = mClientMessenger;
		try {
			mSeverMessenger.send(msg);
		}
		catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			Log.v(TAG, "msg ="+msg.what +", arg1"+msg.arg1);
			switch (msg.what) {
			case BluetoothMessage.msg_status: {
				switch (msg.arg2) {
				case BluetoothMessage.msg_device_detected: {
					@SuppressWarnings("unchecked")
					HashMap<String, Object> result = (HashMap<String, Object>) msg.obj;
					mDevAddress = (String) result.get("detail");
					mRssi = (Integer) result.get("rssi");
					Log.v(TAG, "device received " + mDevAddress);
					if (!mDeviceLists.contains(mDevAddress)) {
						mDeviceLists.add(mDevAddress);
						mRssiLists.add(mRssi);
					}
					Message subMsg2 = handler.obtainMessage(DEVICE_DETECTED);
					subMsg2.obj = mDevAddress;
					for (ICommandCallback item : listeners) {
						item.handleMessage(subMsg2);
					}
				}
					break;
				}

				if (BFactory.isChild(mType, msg.arg1) || BFactory.isChild(msg.arg1,mType)) {
					Message subMsg = handler.obtainMessage(UPDATE_STATUS);
					subMsg.arg1 = msg.arg2;
					if (msg.arg2 == BluetoothMessage.msg_socket_connected
							&& (mType == 105 || mType == 3 || mType == 4)) {
						HashMap<String, Object> result = (HashMap<String, Object>) msg.obj;
						subMsg.arg2 = (Integer) result.get("status");
						subMsg.obj = result.get("detail");
					}
					for (ICommandCallback item : listeners) {
						item.handleMessage(subMsg);
					}
				}
			}
				break;
			case BluetoothMessage.msg_reply: {
				int type = msg.arg1;
				@SuppressWarnings("unchecked")
				HashMap<String, Object> result = (HashMap<String, Object>) msg.obj;
				if (mType == type) {
					Message subMsg = handler.obtainMessage(MEASURE_RESULT);
					subMsg.arg1 = msg.arg2;
					subMsg.arg2 = (Integer) result.get("status");
					subMsg.obj = result.get("detail");

					for (ICommandCallback item : listeners) {
						item.handleMessage(subMsg);
					}
				}
			}
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};
}
